<template>
  <div class="app-container">
    <el-row class="button-row">
      <el-col :span="14">
        <el-button type="primary" :loading="downloading" @click="handleDownload">下载数据</el-button>
        <el-button type="primary" @click="dialogVisible = true">添加数据</el-button>
        <el-button type="success" @click="handleUpload">容错导入</el-button>
        <el-button type="warning" @click="handleClear">清空数据</el-button>
        <el-button type="danger" @click="handleDelete">批量删除</el-button>
        <el-button type="danger" @click="deleteByFilenameDialogVisible = true">按文件名删除</el-button>
      </el-col>
      <el-col :span="10">
        <el-date-picker
          v-model="dateTimePickerVal"
          autocomplete="off"
          type="datetimerange"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          align="right"
          value-format="timestamp"
          format="yyyy-MM-dd HH:mm:ss"
          @change="fetchData"
        />
      </el-col>
    </el-row>
    <div>
      <el-table
        v-model="selectedRows"
        v-loading="listLoading"
        :data="list"
        element-loading-text="Loading"
        border
        stripe
        fit
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55px" />
        <el-table-column align="center" label="就诊类型" min-width="140">
          <template v-slot:header>
            <el-select
              v-model="searchObjVal.treatmentType"
              filterable
              clearable
              placeholder="就诊类型"
              size="small"
              multiple
              @change="fetchData()"
            >
              <el-option
                v-for="item in treatmentTypeDDList"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </template>
          <template slot-scope="scope">
            {{ scope.row.treatmentType }}
          </template>
        </el-table-column>
        <el-table-column label="处方时间" align="center" min-width="180">
          <template slot-scope="scope">
            {{ scope.row.prescriptionTime }}
          </template>
        </el-table-column>
        <el-table-column label="原始处方时间" align="center" min-width="180">
          <template slot-scope="scope">
            {{ scope.row.prescriptionTimeString }}
          </template>
        </el-table-column>
        <el-table-column label="开药医生" align="center">
          <template slot-scope="scope">
            <span>{{ scope.row.prescriber }}</span>
          </template>
        </el-table-column>
        <el-table-column label="患者姓名" align="center" min-width="150">
          <template v-slot:header>
            <el-input
              v-model="searchObjVal.patientName"
              size="small"
              placeholder="患者姓名"
              @input="fetchData()"
            />
          </template>
          <template slot-scope="scope">
            <span>{{ scope.row.patientName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="身份证号码" align="center" min-width="180">
          <template v-slot:header>
            <el-input
              v-model="searchObjVal.idNumber"
              size="small"
              placeholder="身份证号码"
              @input="fetchData()"
            />
          </template>
          <template slot-scope="scope">
            {{ scope.row.idNumber }}
          </template>
        </el-table-column>
        <!--<el-table-column label="重复值" align="center">-->
        <!--  <template slot-scope="scope">-->
        <!--    {{ scope.row.duplicateValue }}-->
        <!--  </template>-->
        <!--</el-table-column>-->
        <el-table-column label="年龄" align="center">
          <template slot-scope="scope">
            {{ scope.row.age }}
          </template>
        </el-table-column>
        <el-table-column label="电话号码" align="center" min-width="150">
          <template v-slot:header>
            <el-input
              v-model="searchObjVal.telephoneNumber"
              size="small"
              placeholder="电话号码"
              @input="fetchData()"
            />
          </template>
          <template slot-scope="scope">
            {{ scope.row.telephoneNumber }}
          </template>
        </el-table-column>
        <el-table-column align="center" min-width="140">
          <template v-slot:header>
            <el-select
              v-model="searchObjVal.drugName"
              filterable
              clearable
              placeholder="药品名称"
              size="small"
              multiple
              @change="fetchData()"
            >
              <el-option
                v-for="item in drugNameDDList"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </template>
          <template slot-scope="scope">
            {{ scope.row.drugName }}
          </template>
        </el-table-column>
        <el-table-column label="规格" align="center">
          <template slot-scope="scope">
            {{ scope.row.specification }}
          </template>
        </el-table-column>
        <el-table-column label="数量" align="center">
          <template slot-scope="scope">
            {{ scope.row.quantity }}
          </template>
        </el-table-column>
        <el-table-column label="剂量" align="center">
          <template slot-scope="scope">
            {{ scope.row.dose }}
          </template>
        </el-table-column>
        <el-table-column align="center" min-width="120">
          <template v-slot:header>
            <el-select
              v-model="searchObjVal.measurementUnit"
              filterable
              clearable
              placeholder="剂量单位"
              size="small"
              multiple
              @change="fetchData()"
            >
              <el-option
                v-for="item in measurementUnitDDList"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </template>
          <template slot-scope="scope">
            {{ scope.row.measurementUnit }}
          </template>
        </el-table-column>
        <el-table-column label="分类" align="center" min-width="140">
          <template v-slot:header>
            <el-select
              v-model="searchObjVal.drugClassification"
              filterable
              clearable
              placeholder="毒麻分类"
              size="small"
              multiple
              @change="fetchData()"
            >
              <el-option
                v-for="item in drugClassificationDDList"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </template>
          <template slot-scope="scope">
            {{ scope.row.drugClassification }}
          </template>
        </el-table-column>
        <el-table-column align="center" min-width="140">
          <template v-slot:header>
            <el-select
              v-model="searchObjVal.hospital"
              filterable
              clearable
              placeholder="医院"
              size="small"
              multiple
              @change="fetchData()"
            >
              <el-option
                v-for="item in hospitalDDList"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </template>
          <template slot-scope="scope">
            {{ scope.row.hospital }}
          </template>
        </el-table-column>
        <el-table-column label="源文件名" align="center" min-width="200px">
          <template slot-scope="scope">
            {{ scope.row.filename }}
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="page-container">
      <el-pagination
        :current-page="page"
        :page-sizes="pageSizes"
        :page-size="size"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!--添加数据 dialog-->
    <el-dialog title="添加数据" :visible.sync="dialogVisible" width="50%" @close="resetForm">
      <el-form ref="form" :model="formData" label-width="120px">
        <el-form-item label="诊断类型" prop="treatmentType">
          <el-input v-model="formData.treatmentType" />
        </el-form-item>
        <el-form-item label="处方时间" prop="prescriptionTime">
          <el-date-picker v-model="formData.prescriptionTime" type="datetime" autocomplete="off" placeholder="选择日期时间" value-format="timestamp" format="yyyy-MM-dd HH:mm:ss" />
        </el-form-item>
        <el-form-item label="开药医生" prop="prescriber">
          <el-input v-model="formData.prescriber" />
        </el-form-item>
        <el-row>
          <el-col :span="8">
            <el-form-item label="患者姓名" prop="patientName">
              <el-input v-model="formData.patientName" />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="年龄" prop="age" label-width="70px">
              <el-input v-model="formData.age" />
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="身份证号" prop="idNumber">
              <el-input v-model="formData.idNumber" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="重复值" prop="duplicateValue">
          <el-input v-model="formData.duplicateValue" />
        </el-form-item>
        <el-form-item label="电话号码" prop="telephoneNumber">
          <el-input v-model="formData.telephoneNumber" />
        </el-form-item>
        <el-form-item label="药品名称" prop="drugName">
          <el-input v-model="formData.drugName" />
        </el-form-item>
        <el-form-item label="规格" prop="specification">
          <el-input v-model="formData.specification" />
        </el-form-item>
        <el-form-item label="数量" prop="quantity">
          <el-input v-model="formData.quantity" />
        </el-form-item>
        <el-form-item label="剂量" prop="dose">
          <el-input v-model="formData.dose" />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="剂量单位" prop="measurementUnit">
              <el-input v-model="formData.measurementUnit" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="毒麻分类" prop="drugClassification">
              <el-input v-model="formData.drugClassification" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="医院名称" prop="hospital">
          <el-input v-model="formData.hospital" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm">确认</el-button>
      </div>
    </el-dialog>

    <!-- Upload Dialog -->
    <el-dialog title="上传文件" :visible.sync="uploadDialogVisible" width="30%" @close="uploadDialogVisible = false">
      <el-upload
        ref="upload"
        v-loading="uploading"
        :action="uploadUrl"
        :on-success="handleUploadSuccess"
        :on-error="handleUploadError"
        :on-progress="handleUploadProgress"
        :before-upload="handleBeforeUpload"
      >
        <el-button slot="trigger" type="primary">选取文件</el-button>
      </el-upload>

      <el-alert
        v-show="uploading"
        style="margin-top: 1em;"
        :title="serverMessage"
        type="success"
        :closable="false"
      />
    </el-dialog>
    <!-- 删除文件名 dialog -->
    <el-dialog title="按删除文件" :visible.sync="deleteByFilenameDialogVisible" width="30%" @close="resetDeleteByFilenameForm">
      <el-form ref="deleteByFilenameForm" :model="deleteByFilenameFormData" label-width="80px">
        <el-form-item label="文件名" prop="filename" :rules="{ required: true, message: '请输入文件名', trigger: 'blur' }">
          <el-input v-model="deleteByFilenameFormData.filename" placeholder="请输入文件名"/>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="deleteByFilenameDialogVisible = false">取消</el-button>
        <el-button :loading="btnLoadingDelByFilename" type="primary" @click="submitDeleteByFilenameForm">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getList, addOneData, batchDelete, downloadByCondition, clear, deleteByFilename } from '@/api/table'
import * as commonApi from '@/api/common'

import '@/styles/table.scss'

export default {
  data() {
    return {
      // 文件上传的地址
      uploadUrl: process.env.VUE_APP_BASE_API + 'data/upload',
      // 添加数据弹窗
      dialogVisible: false,
      // 控制上传文件模态框的显示和隐藏
      uploadDialogVisible: false,
      list: null,
      listLoading: true,
      selectedRows: [],
      // 多条件查询值
      searchObjVal: {
        'treatmentType': [],
        'patientName': '',
        'idNumber': '',
        'drugName': [],
        'measurementUnit': [],
        'drugClassification': [],
        'hospital': [],
        prescriptionStartTime: '',
        prescriptionEndTime: ''
      },
      // 添加数据表单
      formData: {
        treatmentType: '',
        prescriptionTime: '',
        prescriber: '',
        patientName: '',
        idNumber: '',
        duplicateValue: '',
        age: '',
        telephoneNumber: '',
        drugName: '',
        specification: '',
        quantity: '',
        dose: '',
        measurementUnit: '',
        drugClassification: '',
        hospital: ''
      },
      size: 10,
      page: 1,
      total: 0,
      pageSizes: [10, 25, 50, 100],
      // 下拉菜单
      treatmentTypeDDList: [],
      drugNameDDList: [],
      drugClassificationDDList: [],
      measurementUnitDDList: [],
      hospitalDDList: [],
      socket: null,
      uploadProgress: 0,
      // 新增：用于存储服务器返回的消息
      serverMessage: '正在处理数据...',
      // 用于表示是否正在下载
      downloading: false,
      // 用于表示是否正在上传
      uploading: false,
      uploadButtonText: '选取文件',
      // 日期时间选择器的值
      dateTimePickerVal: [],

      // 删除文件对话框
      deleteByFilenameDialogVisible: false,
      deleteByFilenameFormData: {
        filename: ''
      },
      btnLoadingDelByFilename: false
    }
  },
  created() {
    this.fetchData()
    this.fetchDropdownData()

    this.socket = new WebSocket('ws://127.0.0.1:8433/websocket/1')
    this.socket.onmessage = (event) => {
      const data = JSON.parse(event.data)
      if (data.progress) {
        this.uploadProgress = data.progress
      }
      if (data.msg) { // 如果服务器返回了消息，将其保存到 serverMessage 中
        this.serverMessage = data.msg
        this.uploadButtonText = data.msg
      }
    }
  },
  methods: {
    handleUploadProgress(event, file, fileList) {
      // const progress = Math.round((event.loaded / event.total) * 100)
      // this.socket.send(JSON.stringify({ progress }))
    },
    // 日期时间改变
    pickDateTime() {
      this.searchObjVal.prescriptionStartTime = this.dateTimePickerVal[0]
      this.searchObjVal.prescriptionEndTime = this.dateTimePickerVal[1]
    },
    fetchData() {
      this.listLoading = true
      const pageObj = {
        page: this.page,
        size: this.size
      }
      // 同步日期时间
      this.pickDateTime()
      getList(pageObj, this.searchObjVal).then(response => {
        this.list = response.data.list
        this.total = response.data.total
        this.listLoading = false
      })
    },
    // 重置表单
    resetForm() {
      this.$refs.form.resetFields()
    },
    // 提交表单
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          console.log(JSON.stringify(this.formData))
          addOneData(this.formData).then(() => {
            this.$message({
              message: '数据添加成功',
              type: 'success'
            })
            this.dialogVisible = false
            this.resetForm()
          })
        } else {
          return false
        }
      })
    },
    // 分页：页码改变
    handleSizeChange(val) {
      this.size = val
      this.fetchData()
    },
    // 分页：每页显示数量改变
    handleCurrentChange(val) {
      this.page = val
      this.fetchData()
    },
    // 搜索
    searchByWord(type) {
      console.log(type + '-' + JSON.stringify(this.searchObjVal))
    },
    // 按钮点击事件：清空数据
    handleClear() {
      this.$confirm('确定要清空所有数据吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        clear().then(response => {
          if (response.code === 200) {
            this.$message({
              message: response.msg,
              type: 'success'
            })
          } else {
            this.$message({
              message: response.msg,
              type: 'error'
            })
          }
          this.fetchData()
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消清空'
        })
      })
    },
    // 按钮点击事件：批量删除
    handleDelete() {
      this.$confirm('确定要删除选择的数据吗？', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 获取选中行的id
        const ids = this.selectedRows.map(row => row.id)
        batchDelete({ ids }).then(response => {
          if (response.code === 200) {
            this.$message({
              message: response.msg,
              type: 'success'
            })
          } else {
            this.$message({
              message: response.msg,
              type: 'error'
            })
          }
          this.fetchData()
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },

    // 按钮点击事件：上传文件
    handleUpload() {
      // 显示上传文件的模态框
      this.uploadDialogVisible = true
    },
    // 上传文件前的处理函数
    handleBeforeUpload() {
      // 弹出和下载类似的message
      this.$message({
        message: '正在上传，请勿刷新或关闭页面',
        duration: 0
      })
      this.uploading = true
      return true
    },
    // 数据多选选择事件
    handleSelectionChange(val) {
      this.selectedRows = val
    },
    // 文件上传成功的处理函数
    handleUploadSuccess(response) {
      //  关闭 message，仅关闭提示上传中的 message
      this.$message.closeAll()

      if (response.code === 200) {
        this.$message({
          message: response.msg,
          type: 'success'
        })
        // 关闭模态框
        this.uploadDialogVisible = false
        // 清空文件列表
        this.$refs.upload.clearFiles()
        // 重置文本
        this.serverMessage = ''
        // 重新获取数据
        this.fetchData()
      } else {
        this.$message.error('文件上传失败，描述：' + response.msg)
      }
      // 关闭模态框
      this.uploadDialogVisible = false
      // 复原上传按钮
      this.uploading = false
      // 重新获取数据
      this.fetchData()
    },

    // 文件上传失败的处理函数
    handleUploadError(err, file, fileList) {
      this.$message.error('文件上传失败: ' + err.message)
      this.$refs.upload.clearFiles()
      this.$message.closeAll()
      this.fetchData()
    },
    // 按钮点击事件：一键下载数据，按照当前搜索条件下载
    handleDownload() {
      this.$confirm('是否按照当前搜索条件下载所有数据？', '下载确认', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 调用 downloadByCondition 方法
        this.downloading = true // 设置 downloading 为 true
        this.$message({ message: '正在开始下载，请勿刷新或关闭页面', duration: 0 })
        downloadByCondition(this.searchObjVal)
          .then(response => {
            // 处理响应
            // 将文件内容转换为 Blob
            const blob = response.data

            // 创建一个 Blob URL
            const url = window.URL.createObjectURL(blob)

            // 创建一个链接，并将其 href 属性设置为 Blob URL
            const link = document.createElement('a')
            link.href = url

            // 设置下载的文件名
            link.download = `export.xlsx`

            // 将链接添加到文档中
            document.body.appendChild(link)

            // 模拟点击链接
            link.click()

            // 移除链接
            document.body.removeChild(link)
            // 设置 downloading 为 false
            this.downloading = false
            this.$message.closeAll()
          })
          .catch(error => {
            // 处理错误
            console.error(error)
            this.downloading = false
            this.$message.closeAll()
          })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消下载'
        })
      })
    },

    // 格式化：2023-12-23T04:02:13.000+00:00 风格的时间
    formatTime(dateString) {
      const date = new Date(dateString)
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hours = String(date.getHours()).padStart(2, '0')
      const minutes = String(date.getMinutes()).padStart(2, '0')
      const seconds = String(date.getSeconds()).padStart(2, '0')
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    },

    // 获取下拉菜单的数据
    fetchDropdownData() {
      // 获取就诊类型列表
      commonApi.getTreatmentTypeList()
        .then(response => {
          if (response.code === 200) {
            this.treatmentTypeDDList = response.data.list
          } else {
            console.error(response.msg)
          }
        })
        .catch(error => {
          console.error(error)
        })

      // 获取药品分类列表
      commonApi.getDrugClassificationList()
        .then(response => {
          if (response.code === 200) {
            this.drugClassificationDDList = response.data.list
          } else {
            console.error(response.msg)
          }
        })
        .catch(error => {
          console.error(error)
        })

      // 获取药品名称列表
      commonApi.getDrugNameList()
        .then(response => {
          if (response.code === 200) {
            this.drugNameDDList = response.data.list
          } else {
            console.error(response.msg)
          }
        })
        .catch(error => {
          console.error(error)
        })
      // 获取计量单位列表
      commonApi.getMeasurementUnitList()
        .then(response => {
          if (response.code === 200) {
            this.measurementUnitDDList = response.data.list
          } else {
            console.error(response.msg)
          }
        })
        .catch(error => {
          console.error(error)
        })

      // 获取医院列表
      commonApi.getHospitalList()
        .then(response => {
          if (response.code === 200) {
            this.hospitalDDList = response.data.list
          } else {
            console.error(response.msg)
          }
        })
        .catch(error => {
          console.error(error)
        })
    },

    // 提交表单：删除文件 by 文件名
    submitDeleteByFilenameForm() {
      this.btnLoadingDelByFilename = true
      this.$refs.deleteByFilenameForm.validate((valid) => {
        if (valid) {
          deleteByFilename(this.deleteByFilenameFormData)
            .then(response => {
              if (response.code === 200) {
                this.$message({
                  message: '文件删除成功',
                  type: 'success'
                })
                this.deleteByFilenameDialogVisible = false
                this.btnLoadingDelByFilename = false
                this.resetDeleteByFilenameForm()
                this.fetchData()
              }
            })
            .catch(error => {
              this.btnLoadingDelByFilename = false
            })
        } else {
          this.btnLoadingDelByFilename = false
          return false
        }
      })
    },
    resetDeleteByFilenameForm() {
      this.$refs.deleteByFilenameForm.resetFields()
    }
  }

}
</script>
